using System;

namespace Game.Graph
{
    public struct GraphMeta : IComparable, IComparable<GraphMeta>, IEquatable<GraphMeta>
    {
        public ulong a;
        // public ulong b;

        public static readonly GraphMeta Null = new GraphMeta();
        public static uint instId = 0;

        public GraphMeta(uint graphId, GraphNodeType graphNodeType)
        {
            a = ((ulong)graphId << 48) | ((ulong) graphNodeType << 32) | (instId++);
        }

        public uint GraphID => (uint) (a >> 48);

        public GraphNodeType GraphNodeType => (GraphNodeType) (a >> 32);

        public uint GraphInst => (uint) a;
        
        public static bool operator==(in GraphMeta lhs, in GraphMeta rhs) => lhs.a == rhs.a;
        public static bool operator!=(in GraphMeta lhs, in GraphMeta rhs) => !(lhs == rhs);
        
        public override bool Equals(object obj) => obj is GraphMeta guid && Equals(guid);
        
        public bool Equals(GraphMeta other) => a == other.a;
        
        
        public override int GetHashCode()
        {
            // ReSharper disable NonReadonlyMemberInGetHashCode (readonly fields will not get serialized by unity)
            unchecked { return a.GetHashCode(); }
            // ReSharper restore NonReadonlyMemberInGetHashCode
        }

        public int CompareTo(object obj) => obj == null ? 1 : this.CompareTo((GraphMeta) obj);

        public int CompareTo(GraphMeta other)
        {
            if (a != other.a)
                return a > other.a ? 1 : -1;
            return 0;
        }
    }
}